package cn.caplike.demo.rabbitmq.springboot.producer;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ConfirmCallback;
import org.springframework.amqp.rabbit.core.RabbitTemplate.ReturnCallback;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.support.MessageBuilder;
import org.springframework.stereotype.Component;

import java.util.Map;

@Slf4j
@Component
public class MessageProducer {

    // 回调函数: confirm 确认
    final ConfirmCallback confirmCallback = (correlationData, ack, cause) -> {
        log.error("correlationData: " + correlationData);
        log.error("ack: " + ack);
        log.error("cause: " + cause);
        if (!ack) {
            log.error("异常处理....");
        }
        // ack: true 已经发送成功 -> 更新数据库
    };

    /**
     * 回调函数: return 返回, 无法路由到目标 Exchange 时, 需要设置 mandatory 为 true
     */
    final ReturnCallback returnCallback = (message, replyCode, replyText, exchange, routingKey) -> System.err.println(
            "return exchange: " + exchange + ", routingKey: " + routingKey +
                    ", replyCode: " + replyCode + ", replyText: " + replyText
    );

    // -----------------------------------------------------------------------------------------------------------------

    private RabbitTemplate rabbitTemplate;

    @Autowired
    public void setRabbitTemplate(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
    }

    // 发送消息方法调用: 构建 Message 消息
    public void send(Object message, Map<String, Object> properties) {
        MessageHeaders messageHeaders = new MessageHeaders(properties);
        Message<?> msg = MessageBuilder.createMessage(message, messageHeaders);

        rabbitTemplate.setConfirmCallback(confirmCallback);
        rabbitTemplate.setReturnCallback(returnCallback);
        //id + 时间戳 全局唯一
        CorrelationData correlationData = new CorrelationData("1234567890");
        rabbitTemplate.convertAndSend("exchange-1", "springboot.abc", msg, correlationData);
    }

    // 发送消息方法调用: 构建自定义对象消息
//    public void sendOrder(Order order) {
//        rabbitTemplate.setConfirmCallback(confirmCallback);
//        rabbitTemplate.setReturnCallback(returnCallback);
//        //id + 时间戳 全局唯一
//        CorrelationData correlationData = new CorrelationData("0987654321");
//        rabbitTemplate.convertAndSend("exchange-2", "springboot.def", order, correlationData);
//    }

}
